/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.com.jpa.controllers;

import co.com.entities.Contacto;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import co.com.entities.TipoDocumento;
import co.com.entities.Empresa;
import java.util.ArrayList;
import java.util.List;
import co.com.entities.Universidad;
import co.com.jpa.controllers.exceptions.NonexistentEntityException;
import co.com.jpa.controllers.exceptions.PreexistingEntityException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author dloaiza
 */
public class ContactoJpaController implements Serializable {

    public ContactoJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Contacto contacto) throws PreexistingEntityException, Exception {
        if (contacto.getEmpresaList() == null) {
            contacto.setEmpresaList(new ArrayList<Empresa>());
        }
        if (contacto.getUniversidadList() == null) {
            contacto.setUniversidadList(new ArrayList<Universidad>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            TipoDocumento nmidTipoDocumento = contacto.getNmidTipoDocumento();
            if (nmidTipoDocumento != null) {
                nmidTipoDocumento = em.getReference(nmidTipoDocumento.getClass(), nmidTipoDocumento.getIdTipoDocumento());
                contacto.setNmidTipoDocumento(nmidTipoDocumento);
            }
            List<Empresa> attachedEmpresaList = new ArrayList<Empresa>();
            for (Empresa empresaListEmpresaToAttach : contacto.getEmpresaList()) {
                empresaListEmpresaToAttach = em.getReference(empresaListEmpresaToAttach.getClass(), empresaListEmpresaToAttach.getDsnit());
                attachedEmpresaList.add(empresaListEmpresaToAttach);
            }
            contacto.setEmpresaList(attachedEmpresaList);
            List<Universidad> attachedUniversidadList = new ArrayList<Universidad>();
            for (Universidad universidadListUniversidadToAttach : contacto.getUniversidadList()) {
                universidadListUniversidadToAttach = em.getReference(universidadListUniversidadToAttach.getClass(), universidadListUniversidadToAttach.getNmidUniversidad());
                attachedUniversidadList.add(universidadListUniversidadToAttach);
            }
            contacto.setUniversidadList(attachedUniversidadList);
            em.persist(contacto);
            if (nmidTipoDocumento != null) {
                nmidTipoDocumento.getContactoList().add(contacto);
                nmidTipoDocumento = em.merge(nmidTipoDocumento);
            }
            for (Empresa empresaListEmpresa : contacto.getEmpresaList()) {
                Contacto oldDsidContactoOfEmpresaListEmpresa = empresaListEmpresa.getDsidContacto();
                empresaListEmpresa.setDsidContacto(contacto);
                empresaListEmpresa = em.merge(empresaListEmpresa);
                if (oldDsidContactoOfEmpresaListEmpresa != null) {
                    oldDsidContactoOfEmpresaListEmpresa.getEmpresaList().remove(empresaListEmpresa);
                    oldDsidContactoOfEmpresaListEmpresa = em.merge(oldDsidContactoOfEmpresaListEmpresa);
                }
            }
            for (Universidad universidadListUniversidad : contacto.getUniversidadList()) {
                Contacto oldDsidContactoOfUniversidadListUniversidad = universidadListUniversidad.getDsidContacto();
                universidadListUniversidad.setDsidContacto(contacto);
                universidadListUniversidad = em.merge(universidadListUniversidad);
                if (oldDsidContactoOfUniversidadListUniversidad != null) {
                    oldDsidContactoOfUniversidadListUniversidad.getUniversidadList().remove(universidadListUniversidad);
                    oldDsidContactoOfUniversidadListUniversidad = em.merge(oldDsidContactoOfUniversidadListUniversidad);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findContacto(contacto.getDsidentificacion()) != null) {
                throw new PreexistingEntityException("Contacto " + contacto + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Contacto contacto) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Contacto persistentContacto = em.find(Contacto.class, contacto.getDsidentificacion());
            TipoDocumento nmidTipoDocumentoOld = persistentContacto.getNmidTipoDocumento();
            TipoDocumento nmidTipoDocumentoNew = contacto.getNmidTipoDocumento();
            List<Empresa> empresaListOld = persistentContacto.getEmpresaList();
            List<Empresa> empresaListNew = contacto.getEmpresaList();
            List<Universidad> universidadListOld = persistentContacto.getUniversidadList();
            List<Universidad> universidadListNew = contacto.getUniversidadList();
            if (nmidTipoDocumentoNew != null) {
                nmidTipoDocumentoNew = em.getReference(nmidTipoDocumentoNew.getClass(), nmidTipoDocumentoNew.getIdTipoDocumento());
                contacto.setNmidTipoDocumento(nmidTipoDocumentoNew);
            }
            List<Empresa> attachedEmpresaListNew = new ArrayList<Empresa>();
            for (Empresa empresaListNewEmpresaToAttach : empresaListNew) {
                empresaListNewEmpresaToAttach = em.getReference(empresaListNewEmpresaToAttach.getClass(), empresaListNewEmpresaToAttach.getDsnit());
                attachedEmpresaListNew.add(empresaListNewEmpresaToAttach);
            }
            empresaListNew = attachedEmpresaListNew;
            contacto.setEmpresaList(empresaListNew);
            List<Universidad> attachedUniversidadListNew = new ArrayList<Universidad>();
            for (Universidad universidadListNewUniversidadToAttach : universidadListNew) {
                universidadListNewUniversidadToAttach = em.getReference(universidadListNewUniversidadToAttach.getClass(), universidadListNewUniversidadToAttach.getNmidUniversidad());
                attachedUniversidadListNew.add(universidadListNewUniversidadToAttach);
            }
            universidadListNew = attachedUniversidadListNew;
            contacto.setUniversidadList(universidadListNew);
            contacto = em.merge(contacto);
            if (nmidTipoDocumentoOld != null && !nmidTipoDocumentoOld.equals(nmidTipoDocumentoNew)) {
                nmidTipoDocumentoOld.getContactoList().remove(contacto);
                nmidTipoDocumentoOld = em.merge(nmidTipoDocumentoOld);
            }
            if (nmidTipoDocumentoNew != null && !nmidTipoDocumentoNew.equals(nmidTipoDocumentoOld)) {
                nmidTipoDocumentoNew.getContactoList().add(contacto);
                nmidTipoDocumentoNew = em.merge(nmidTipoDocumentoNew);
            }
            for (Empresa empresaListOldEmpresa : empresaListOld) {
                if (!empresaListNew.contains(empresaListOldEmpresa)) {
                    empresaListOldEmpresa.setDsidContacto(null);
                    empresaListOldEmpresa = em.merge(empresaListOldEmpresa);
                }
            }
            for (Empresa empresaListNewEmpresa : empresaListNew) {
                if (!empresaListOld.contains(empresaListNewEmpresa)) {
                    Contacto oldDsidContactoOfEmpresaListNewEmpresa = empresaListNewEmpresa.getDsidContacto();
                    empresaListNewEmpresa.setDsidContacto(contacto);
                    empresaListNewEmpresa = em.merge(empresaListNewEmpresa);
                    if (oldDsidContactoOfEmpresaListNewEmpresa != null && !oldDsidContactoOfEmpresaListNewEmpresa.equals(contacto)) {
                        oldDsidContactoOfEmpresaListNewEmpresa.getEmpresaList().remove(empresaListNewEmpresa);
                        oldDsidContactoOfEmpresaListNewEmpresa = em.merge(oldDsidContactoOfEmpresaListNewEmpresa);
                    }
                }
            }
            for (Universidad universidadListOldUniversidad : universidadListOld) {
                if (!universidadListNew.contains(universidadListOldUniversidad)) {
                    universidadListOldUniversidad.setDsidContacto(null);
                    universidadListOldUniversidad = em.merge(universidadListOldUniversidad);
                }
            }
            for (Universidad universidadListNewUniversidad : universidadListNew) {
                if (!universidadListOld.contains(universidadListNewUniversidad)) {
                    Contacto oldDsidContactoOfUniversidadListNewUniversidad = universidadListNewUniversidad.getDsidContacto();
                    universidadListNewUniversidad.setDsidContacto(contacto);
                    universidadListNewUniversidad = em.merge(universidadListNewUniversidad);
                    if (oldDsidContactoOfUniversidadListNewUniversidad != null && !oldDsidContactoOfUniversidadListNewUniversidad.equals(contacto)) {
                        oldDsidContactoOfUniversidadListNewUniversidad.getUniversidadList().remove(universidadListNewUniversidad);
                        oldDsidContactoOfUniversidadListNewUniversidad = em.merge(oldDsidContactoOfUniversidadListNewUniversidad);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                String id = contacto.getDsidentificacion();
                if (findContacto(id) == null) {
                    throw new NonexistentEntityException("The contacto with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(String id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Contacto contacto;
            try {
                contacto = em.getReference(Contacto.class, id);
                contacto.getDsidentificacion();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The contacto with id " + id + " no longer exists.", enfe);
            }
            TipoDocumento nmidTipoDocumento = contacto.getNmidTipoDocumento();
            if (nmidTipoDocumento != null) {
                nmidTipoDocumento.getContactoList().remove(contacto);
                nmidTipoDocumento = em.merge(nmidTipoDocumento);
            }
            List<Empresa> empresaList = contacto.getEmpresaList();
            for (Empresa empresaListEmpresa : empresaList) {
                empresaListEmpresa.setDsidContacto(null);
                empresaListEmpresa = em.merge(empresaListEmpresa);
            }
            List<Universidad> universidadList = contacto.getUniversidadList();
            for (Universidad universidadListUniversidad : universidadList) {
                universidadListUniversidad.setDsidContacto(null);
                universidadListUniversidad = em.merge(universidadListUniversidad);
            }
            em.remove(contacto);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Contacto> findContactoEntities() {
        return findContactoEntities(true, -1, -1);
    }

    public List<Contacto> findContactoEntities(int maxResults, int firstResult) {
        return findContactoEntities(false, maxResults, firstResult);
    }

    private List<Contacto> findContactoEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Contacto.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Contacto findContacto(String id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Contacto.class, id);
        } finally {
            em.close();
        }
    }

    public int getContactoCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Contacto> rt = cq.from(Contacto.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
